When writing source code during the development of software applications, developers commonly spend a significant amount of time “debugging” the source code to find runtime errors in the code. For example, a developer may take several approaches to reproduce and localize a source code bug, such as observing behavior of a program based on different inputs, inserting debugging code (e.g., to print variable values, to track branches of execution, etc.), temporarily removing code portions, etc. Tracking down runtime errors to pinpoint code bugs and occupy a significant portion of application development time.
Debugging applications (“debuggers”) have been developed in order to assist with the code debugging process. Many such tools offer the ability to trace, visualize, and alter the execution of computer code. For example, debuggers may visualize the execution of code instructions (e.g., source code, assembly code, etc.) and variable values, and enable the user to alter aspects of the code execution. Commonly, debuggers enable a user to set “breakpoints” in source code (e.g., a particular instruction or statement in source code) which, when reached during execution, cause execution of the program to be suspended. When source code execution is suspended, a user may be presented variable values and be given options to choose how to proceed (e.g., by terminating execution, by continuing execution as normal, by stepping into, over, or out of statements/function calls, etc.). However, classic debuggers only enable code execution to be observed/altered in a single direction—forward. For example, classic debuggers do not enable a user to choose to go back to a prior breakpoint.
An emerging form of debugging is “time travel” debugging, in which execution of a program is recorded into a trace, which can be then be replayed and analyzed both forwards and backwards.